/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package be.ugent.medirem.persistence.facade;

import be.ugent.medirem.persistence.entity.MeasurementType;
import be.ugent.medirem.persistence.entity.Medication;
import be.ugent.medirem.persistence.entity.Unit;
import be.ugent.medirem.persistence.entity.details.MedicationDetails;
import be.ugent.medirem.persistence.entity.values.MedicationValues;
import be.ugent.medirem.persistence.exception.EntityNotFoundException;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author Thomas Roelens <thomas.roelens@ugent.be>
 */
@Stateless
public class MedicationDaoBean implements MedicationDaoLocal {

    @PersistenceContext
    private EntityManager em;
    @EJB
    private MeasurementTypeDaoLocal measurementTypeDaoBean;

    public Long create(MedicationValues details) throws IllegalArgumentException, EntityNotFoundException {
        Medication medication = null;
        Unit unit = null;
        MeasurementType measurementType = null;

        if (details.getName() == null) {
            throw new IllegalArgumentException("Medication name is null");
        } else if (details.getStdDose() < 0) {
            throw new IllegalArgumentException("Medication value is invalid");
        } else if (details.getUnitId() == null) {
            throw new IllegalArgumentException("Medication unit id is null");
        }

        try {
            unit = em.find(Unit.class, details.getUnitId());
            measurementType = em.find(MeasurementType.class, details.getMeasurementTypeId());

        } catch (Exception ex) {
            throw new EJBException(ex);
        }
        if (unit == null) {
            throw new EntityNotFoundException("Unit not found : " + details.getUnitId());
        }

        try {
            medication = new Medication(details.getName(), details.getStdDose(), unit, measurementType);
            persist(medication);
        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        return medication.getId();
    }

    public void remove(Long medicationId) throws IllegalArgumentException, EntityNotFoundException {
        Medication medication = null;
        if (medicationId == null) {
            throw new IllegalArgumentException("Medication id is null");
        }
        try {
            medication = em.find(Medication.class, medicationId);

            if (medication == null) {
                throw new EntityNotFoundException();
            } else {
                medication = em.merge(medication);
                em.remove(medication);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public void update(Long medicationId, MedicationValues details) throws IllegalArgumentException, EntityNotFoundException {
        Medication medication = null;
        if (medicationId == null) {
            throw new IllegalArgumentException("Medication id is null");
        }
        try {
            medication = em.find(Medication.class, medicationId);

            if (medication == null) {
                throw new EntityNotFoundException();
            } else {
                if (details.getName() != null) {
                    medication.setName(details.getName());
                }
                if (details.getStdDose() != 0) {
                    medication.setStdDose(details.getStdDose());
                }
                if (details.getUnitId() != null) {
                    Unit newUnit = em.find(Unit.class, details.getUnitId());
                    medication.setUnitDose(newUnit);
                }
                em.merge(medication);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }
    }

    public MedicationDetails getDetails(Long medicationId) throws IllegalArgumentException, EntityNotFoundException {
        Medication medication = null;
        MedicationDetails details = null;

        if (medicationId == null) {
            throw new IllegalArgumentException("Medication id is null");
        }
        try {
            medication = em.find(Medication.class, medicationId);

            if (medication == null) {
                throw new EntityNotFoundException();
            } else {
                details = convert(medication);
            }
        } catch (Exception ex) {
            throw new EJBException(ex);
        }

        return details;
    }

    public List<MedicationDetails> search(String medicationName) {
        List<MedicationDetails> details = new ArrayList<MedicationDetails>();

        // TODO: try catch nodig?
        List<Medication> meds = em.createNamedQuery("Medication.Search").setParameter("name", "%" + medicationName + "%").getResultList();
        for (Medication m : meds) {
            details.add(convert(m));
        }

        return details;
    }

    public List<MedicationDetails> getAllMedications() {
        List<MedicationDetails> details = new ArrayList<MedicationDetails>();

        // TODO: try catch nodig?
        List<Medication> meds = em.createNamedQuery("Medication.FindAll").getResultList();
        for (Medication m : meds) {
            details.add(convert(m));
        }

        return details;
    }

    public void persist(Object object) {
        em.persist(object);
    }
    
    private MedicationDetails convert(Medication m){
        if(m == null) {
            return null;
        }
        return new MedicationDetails(m.getId(), m.getName(), m.getStdDose(),
                        m.getUnitDose().getName(), 
                        m.getMeasurementType() != null ? m.getMeasurementType().getName() : null);
    }


}
